#pragma once

namespace ShRp
{
	struct WindowsMessage
	{
		enum E
		{
			Paint = 0,
			Destroy,
			MouseMove,
			MouseDown,
			MouseUp,
			KeyDown,
			KeyRepeat,
			KeyUp
		};
	};

	struct MouseButton
	{
		enum E
		{
			Left = 0,
			Middle,
			Right,
			Mouse4,
			Mouse5,
			Max
		};
	};

	struct Mouse
	{
		static void SetPos(int2 _NewPos)								{	LastPos = Pos;	Pos = _NewPos;	}
		static void SetButtonState(MouseButton::E _Button, bool _State)	{	m_Buttons[_Button] = _State;			}

		static int2 Pos, LastPos;

		static int2 GetButtonState(MouseButton::E _Button)				{	return m_Buttons[_Button];				}
	private:
		static bool m_Buttons[MouseButton::Max];
	};

	struct Key
	{
		enum En
		{
			Backspace = 0x08,
			Tab,
			Enter = 0x0D,
			Shift = 0x10, Control, Alt,
			Pause,
			Capslock,
			Escape = 0x1B,
			Space = 0x20,
			PageUp, PageDown, End, Home,
			Left, Up, Right, Down,
			PrintScreen = 0x2C,
			Insert, Delete,
			Zero = 0x30, One, Two, Three, Four, Five, Six, Seven, Eight, Nine,
			A = 0x41, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z,
			WindowsLeft, WindowsRight,
			Num0 = 0x60, Num1, Num2, Num3, Num4, Num5, Num6, Num7, Num8, Num9,
			Multiply, Add, Subtract = 0x6D, Divide = 0x6F,
			F1 = 0x70, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24,
			ShiftLeft = 0xA0, RightShift, LeftControl, RightControl, LeftAlt, RightAlt,
			Comma = 0xBB, Minus, Dot,
			Max = 0xFF
		};
	};
	class Keyboard
	{
	public:
		static void SetKeyState(Key::En _Key, bool _State)	{	m_Keys[_Key] = _State;	}
		static bool GetKeyState(Key::En _Key)				{	return m_Keys[_Key];	}

	private:
		static bool m_Keys[Key::Max];
	};

	// Checks the 30th bit of the wparam.
#	define GetPrevKeyState(wparam)	((wparam & 0x40000000) != 0)
#	ifdef _DEBUG
		// Simple Assert, does not exist in release.
#		define assert(a)	{if(!a) Error("Assert Failed: (%s).\n", #a)		  }
#	else // _DEBUG
		// Simple Assert, does not exist in release.
#		define assert(a) ()
#	endif
	// Checks if a file exists.
	bool FileExists( const char* _FileName );
};

typedef unsigned int uint;
typedef unsigned short ushort;
typedef unsigned char uchar;